import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

/*
WebSocketChannel提供了一个来自服务器的消息Stream 。

该Stream类是dart:async包中的一个基础类。它提供了一种方法来监听来自数据源的异步事件。与Future返回单个异步响应不同，Stream类可以随着时间推移传递很多事件。

该StreamBuilder Widget将连接到一个Stream， 并在每次收到消息时通知Flutter重新构建界面。
 */

class MyHomePage extends StatefulWidget{
  final String title;
  final WebSocketChannel channel;

  MyHomePage({Key? key, required this.title, required this.channel}) : super(key: key);
  @override
  State<StatefulWidget> createState() {
    return _MyHomePageState();
  }
}

class _MyHomePageState extends State<MyHomePage>{
  TextEditingController _controller = TextEditingController();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.title),),
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Form(child: TextFormField(
              controller: _controller,
              decoration: InputDecoration(labelText: 'Send a message'),
            )),
            StreamBuilder(builder: (BuildContext context, AsyncSnapshot snapshot){
              return Padding(padding: const EdgeInsets.symmetric(vertical: 24.0),
              child: Text(snapshot.hasData ? '${snapshot.data}' : ''),);
            },
            stream: widget.channel.stream,)
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _sendMessage,
        tooltip: 'Send message',
        child: Icon(Icons.send),
      ),
    );
  }

  void _sendMessage(){
    if(_controller.text.isNotEmpty){
      widget.channel.sink.add(_controller.text);
    }
  }

  @override
  void dispose() {
    widget.channel.sink.close();
    super.dispose();
  }
}

class WebSocketsEx extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return MyHomePage(title: 'WebSocket Demo', channel: IOWebSocketChannel.connect('ws://echo.websocket.org'));
  }
}